package cc.rengu.igas.channel.cups.core.service.base;

import cc.rengu.igas.channel.cups.common.constant.CupsTreeNodeConstant;
import cc.rengu.igas.channel.cups.core.model.ChnlBizResponse;
import cc.rengu.igas.channel.cups.facade.base.BaseRequest;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.DstChannelInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.DstChannelInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.DstChannelInfo;
import cc.rengu.oltp.service.common.entity.DstTxnAuthCfg;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;

/**
 * cups管理类交易基类
 *
 * @author who
 */
public abstract class BaseManageService<T, U> extends RadpService {
    @Override
    protected int bizInit(String s) {
        return 0;
    }

    @Override
    protected int bizProcess(String s, int i) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        try {
            /* Step1：通道(交易)权限检查 */
            rglog.info("---------------> 通道(交易)权限检查 <---------------");
            channelPermissionCheck();
            /* Step2：业务处理前实现接口 */
            rglog.info("---------------> 业务处理前处理 <---------------");
            T request = beforeBizProcess();

            /* Step3：公共字段统一处理 */

            /* Step4：业务逻辑处理 */
            rglog.info("---------------> 业务逻辑处理 <---------------");
            ChnlBizResponse<U> response = callBizService(request);
            /* Step4：业务处理后实现接口 */
            rglog.info("---------------> 业务处理后处理 <---------------");
            afterBizProcess(response);
        } catch (Exception e) {
            String respCode;
            String respMsg;

            rglog.error("业务异常信息:<{}>", cc.rengu.utility.base.StringUtil.ExceptionToString(e));
            if (e instanceof BizException) {
                respCode = ((BizException) e).getCode();
                respMsg = e.getMessage();
                rglog.error("业务处理失败，业务返回码:<{}>，业务返回信息:<{}>", respCode, respMsg);
            } else {
                rglog.error("系统处理失败，返回信息:<{}>", e);
                respCode = OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode();
                respMsg = OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc();
            }
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, respCode);
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, respMsg);
            } catch (Exception ex) {
                rglog.error("设置节点值异常信息:<{}>", cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                return -1;
            }

        }
        return 0;
    }

    @Override
    protected int bizTerminate(String s) {
        return 0;
    }

    /**
     * 业务调用前处理
     *
     * @return 业务处理请求结构
     * @throws Exception 失败抛出异常
     */
    protected abstract T beforeBizProcess() throws Exception;

    /**
     * 业务处理服务调用
     *
     * @param request 业务处理信息
     * @return 业务处理应答结果
     * @throws Exception 失败抛出异常
     */
    protected abstract ChnlBizResponse<U> callBizService(T request) throws Exception;

    /**
     * 业务调用后处理
     *
     * @param response 业务响应结果
     * @throws Exception 失败抛出异常
     */
    protected abstract void afterBizProcess(ChnlBizResponse<U> response) throws Exception;

    /**
     * 通道、交易权限权限
     *
     * @throws Exception 业务处理异常
     */
    private void channelPermissionCheck() throws Exception {
        BaseRequest baseRequest = new BaseRequest();
        ConvertUtil.convertOutput(baseRequest);
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = baseRequest.getHeader().getInstId();
        String txnNum = baseRequest.getHeader().getTxnNum();
        rglog.info("instId:[{}],txnNum:[{}]", instId, txnNum);
        /* 通道状态检查 */
        String dstChannelKey = instId + ChannelEnum.CUPS.getChannelType();
        DstChannelInfo dstChannelInfo = JSON.parseObject(RedisUtil.hashGet(AppParamConstant.CHANNEL_ISS_INFO_CACHE, dstChannelKey), DstChannelInfo.class);
        if (null == dstChannelInfo) {
            DstChannelInfoMapper dstChannelInfoMapper = new DstChannelInfoMapperImpl();
            dstChannelInfo = dstChannelInfoMapper.selectDstChannelInfoByPrimaryKey(instId, ChannelEnum.CUPS.getChannelType());
        }
        if (null == dstChannelInfo || !dstChannelInfo.getDstChannelStatus().equalsIgnoreCase(AppParamConstant.YES)) {
            rglog.error("支付渠道<{}-{}>未配置或已停用！", ChannelEnum.CUPS.getChannelType(), (null == dstChannelInfo) ? "" : dstChannelInfo.getDstChannelName());
            throw new BizException(OltpRpcdEnum.CHANNEL_DISABLED);
        }

        xmlTreeUtil.setXmlTreeObjectValue(CupsTreeNodeConstant.DST_CHANNEL_INFO, dstChannelInfo);

        /**银联CUPS发过来的，管理类交易不检查*/
        if (!"M00CU0".equals(txnNum.substring(0, 6))) {
            String dstChannelAuthKey = instId.trim() + ChannelEnum.CUPS.getChannelType() + txnNum.trim();
            DstTxnAuthCfg dstTxnAuthCfg = JSON.parseObject(RedisUtil.hashGet(AppParamConstant.CHANNEL_TXN_CACHE, dstChannelAuthKey), DstTxnAuthCfg.class);
            if (null == dstTxnAuthCfg || !dstTxnAuthCfg.getSupportFlag().equalsIgnoreCase(AppParamConstant.YES)) {
                rglog.error("支付通道<{}-{}>不支持此交易，通道交易码:<{}>", dstChannelInfo.getDstChannelId(), dstChannelInfo.getDstChannelName(), txnNum);
                throw new BizException(OltpRpcdEnum.TRANS_NOT_SUPPORT);
            }
            xmlTreeUtil.setXmlTreeObjectValue(CupsTreeNodeConstant.DST_TXN_AUTH_CFG, dstTxnAuthCfg);
            if (dstTxnAuthCfg.getMsgRegisterFlag() != null && dstTxnAuthCfg.getMsgRegisterFlag().isEmpty()) {
                xmlTreeUtil.setXmlTreeStringValue(CupsTreeNodeConstant.MSG_REG_FLAG, dstTxnAuthCfg.getMsgRegisterFlag());
            }
        }
    }
}
